/*******************************************************************************
 * Copyright (c) 2011 Jovansonlee B. Cesar.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the GNU Public License v2.0
 * which accompanies this distribution, and is available at
 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
 * 
 * Contributors:
 *     Jovansonlee B. Cesar - initial API and implementation
 ******************************************************************************/
package com.ivanceras.shared.db;

import java.io.Serializable;
import java.util.Arrays;

import com.ivanceras.shared.exception.ModelDefinitionNotFoundException;
import com.ivanceras.shared.meta.ModelDefinitionProvider;



public class Join implements Serializable {
	/**
	 * 
	 */
	private static final long serialVersionUID = 7831613344862076932L;
	public static String LEFT = "LEFT";
	public static String RIGHT = "RIGHT";
	
	private String joinType = LEFT; //default join type
	
	private ModelDef firstModel;
	private ModelDef foreignModel;
	
	public Join(){
		
	}
	
	public Join(ModelDef firstModel, ModelDef foreignModel, String joinType){
		this.firstModel = firstModel;
		this.foreignModel = foreignModel;
		this.joinType = joinType;
	}
	
	public ModelDef getFirstModel(){
		return this.firstModel;
	}
	
	public ModelDef getForeignModel(){
		return this.foreignModel;
	}
	
	public String getJoinType(){
		return this.joinType;
	}
	
	@Override
	public String toString(){
		StringBuffer sql = new StringBuffer();
		String joinType = this.getJoinType();

		ModelDef model = this.getFirstModel();
		ModelDef foreignModel = this.getForeignModel();

		String modelName = model.getModelName();//Partner
		String foreignTableName = foreignModel.getModelName(); //Advertiser

		String[] primaryKeys = this.getFirstModel().getPrimaryColumns();//Partner.partnerid
		String[] foreignKeys = model.getForeignKeyColumns(foreignTableName);//Advertiser.partnerid
		String[] localColumns = model.getLocalColumns(foreignTableName);

		String schema = model.getNamespace();
		if(schema != null){
			sql.append(schema+".");
		}
		sql.append(DB_Rdbms.getDBElementName(model, model.getModelName())+" ");
		sql.append(joinType+" JOIN ");
		String fschema = foreignModel.getNamespace();
		if(fschema != null){
			sql.append(fschema+".");
		}
		sql.append(DB_Rdbms.getDBElementName(foreignModel, foreignTableName));
		String foreignTableAlias = DB_Rdbms.getDBElementName(foreignModel, foreignTableName);
		if(model.getModelName().equals(foreignTableName)){
			foreignTableAlias = foreignTableAlias+"_Alias";
			sql.append(" AS "+foreignTableAlias);
		}

		sql.append(" ON ");
		boolean doAnd = false;
		if(foreignKeys != null){
			for(int i = 0; i < foreignKeys.length; i++){
				if(doAnd){sql.append(" AND ");}else{doAnd = true;}
				sql.append(DB_Rdbms.getDBElementName(model, modelName)+"."+DB_Rdbms.getDBElementName(model, localColumns[i]));//Partner.partnerid
				sql.append(" = ");
				sql.append(DB_Rdbms.getDBElementName(foreignModel, foreignTableAlias)+"."+DB_Rdbms.getDBElementName(foreignModel, foreignKeys[i]));//Advertiser.partnerid
			}
		}
		return sql.toString();
	}
	
	public static void main(String[] args) throws ModelDefinitionNotFoundException{
		ModelDef model1 = ModelDefinitionProvider.getDefinition("Ad_tab");
		ModelDef model2 = ModelDefinitionProvider.getDefinition("Ad_field");
		Join j = new Join(model1, model2, Join.LEFT);
		System.out.println(j);
	}
}
